#include "Application.h"
#include <iostream>

Application::Application(int width, int height, std::string title)
{

	runApplication = true;
	nextGameTick = getTime();

	screenWidth = width;
	screenHeight = height;
	createWindow(width, height, title);
	glewInit();

	seedRand( getTime() );

	Shader().initializeShaderContext();

	counter = 0;
	renderFPS = 0;
	oldTime = getTime();

	try
	{
		defaultFont = new Font("media/fonts/default.ttf", 16);
		currentFont = defaultFont;
	}catch(std::exception &e)
	{
		std::cout << e.what();
		currentFont = NULL;
	}

}

Application::~Application(void)
{
	Shader().destroyShaderContext();
	delete defaultFont;
}

int Application::getScreenWidth(){ return screenWidth; }
int Application::getScreenHeight(){ return screenHeight; }

void Application::drawText(int x, int y, std::string text)
{
	if(currentFont)
		currentFont->drawText(x, y, text);
}

void Application::drawText(int x, int y, int text)
{
	std::string s = "";
	append(s, text);
	if(currentFont)
		currentFont->drawText(x, y, s);
}
void Application::drawText(int x, int y, float text)
{
	std::string s = "";
	append(s, text);
	if(currentFont)
		currentFont->drawText(x, y, s);
}

void Application::setFont(Font* font)
{
	currentFont = font;
}

void Application::createWindow(int width, int height, std::string title)
{
	SDL_Surface *screen;
	if ( SDL_Init(SDL_INIT_VIDEO) != 0 ){
		printf("Unable to initialize SDL: %s\n", SDL_GetError());
	}
	SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
	SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
	SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
	SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
	SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
	SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0 ); //disable vsync

	setWindowTitle(title);
	screen = SDL_SetVideoMode( width, height, 16, SDL_OPENGL | SDL_GL_DOUBLEBUFFER );
	//screen = SDL_SetVideoMode( width, height, 16, SDL_OPENGLBLIT );
	glEnable(GL_TEXTURE_2D);

	enable2D();
}
void Application::enable2D()
{
	GLint iViewport[4];
	glGetIntegerv( GL_VIEWPORT, iViewport );
	glMatrixMode( GL_PROJECTION );
	glPushMatrix();
	glLoadIdentity();
	glOrtho( iViewport[0], iViewport[0]+iViewport[2],
			 iViewport[1]+iViewport[3], iViewport[1], -1000, 1000 );
	glMatrixMode( GL_MODELVIEW );
	glPushMatrix();
	glLoadIdentity();
	glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT );
	glDisable( GL_DEPTH_TEST );
	glDisable( GL_LIGHTING );
}

void Application::disable2D()
{
	glPopAttrib();
	glMatrixMode( GL_PROJECTION );
	glPopMatrix();
	glMatrixMode( GL_MODELVIEW );
	glPopMatrix();
}

unsigned long Application::getTime()
{
	return SDL_GetTicks();
}

void Application::setWindowTitle(std::string s)
{
	SDL_WM_SetCaption(s.c_str(), s.c_str());
}

void Application::clear()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void Application::run()
{
	runApp();
}

void Application::runApp()
{

	while(runApplication)
	{
		
		for(int loops=0; loops<MAX_FRAMESKIP && getTime() > nextGameTick; loops++)
		{
			nextGameTick += SKIP_TICKS;

			Input().detectInput();
			Shader().updateTimers();

			this->update();
		
		}
		float interpolation = float( getTime() + SKIP_TICKS - nextGameTick ) / float( SKIP_TICKS );
		clear();

		counter++;
		if(getTime() - oldTime >= 1000)
		{
			renderFPS = counter;
			oldTime = getTime();
			counter = 0;
		}
		this->render(interpolation);

		glFlush();
		SDL_GL_SwapBuffers();
		SDL_Delay(1); //don't use 100% of the processor.
	}
}


void Application::render(float interpolation)
{

}

void Application::update()
{
}